<template>
  <div :id="'container' + id" class="plane-view-container" :style="{ height: height }">
    <div class="title">{{ title[type] }}</div>
    <p class="rect-info">{{ rectInfo }}</p>
    <p class="update-rect-info" v-show="updateRectInfo != ''">
      {{ updateRectInfo }}
      <span class="operator">
        <button>保存</button>&nbsp;
        <button @click="cancelSave">取消</button>
      </span>
    </p>
    <canvas :id="'canvas3d' + id" class="canvas" />
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { colorRender } from '../../PCDColorRender'

export default {
  name: 'PlaneView',
  props: {
    id: String,
    type: Number,
    height: String,
    visable: Boolean,
    renderType: String,
    attributeNames: {},
    colorNames: {},
    pointsCloudData: Object,
    selectedObject: Object,
  },
  data() {
    return {
      title: ['俯视', '侧视', '前视'],
      rectInfo: '',
      updateRectInfo: '',
      cube: null,
      vertices: [],
      centerPoints: [],
      selectedObjectRendered: false,
      old_planeMesh: null,
      planeMesh: null,
      old_planeLine: null,
      planeLine: null,
      old_keyPoints: null,
      keyPoints: null,
      animationFrameId: undefined,
      mouseDown: false,
      renderEnabled: false,
      container: null,
      camera: null,
      raycaster: null,
      mouse: null,
      mouseX: null,
      mouseY: null,
      moveIndex1: null,
      moveIndex2: null,
      directionx: 1,
      directiony: 1,
      scene: null,
      controls: null,
      renderer: null,
      clientRect: null,
      clonePointsCloudData: null,
      points: null,
      INTERSECTED: null,
      oldRectPoints: [],
      cubeMesh: null,
      line: null,
    }
  },
  created() {},
  mounted() {
    window.addEventListener('resize', this.resize, false)
  },
  beforeDestroy() {
    cancelAnimationFrame(this.animationFrameId)
    this.camera = null
    if (this.renderer) {
      this.renderer.forceContextLoss()
      this.renderer = null
    }
    window.removeEventListener('resize', this.resize, false)
  },
  watch: {
    visable: function (val, oldVal) {
      if (val) {
        if (this.container) {
          this.resize()
        } else {
          this.init()
        }
        if (!this.points) {
          // 未加载过点云
          this.pointsRender()
        }
        if (this.selectedObjectRendered) {
          this.planeRender(this.getViewRectPoints(this.type))
          this.resetCameraPosition()
        }
      }
    },
    pointsCloudData: function (val, oldVal) {
      if (val) {
        if (this.container) {
          this.pointsRender()
        }
      }
    },
    selectedObject: function (val, oldVal) {
      if (val && val.a1 != '') {
        this.selectedObjectRendered = true
        if (this.container && this.visable) {
          this.planeRender(this.getViewRectPoints(this.type))
          this.resetCameraPosition()
        }
      } else {
        this.setCubeInfo(null)
        this.removeOldPlaneRender()
        this.vertices.splice(0, this.vertices.length)
      }
      this.cancelSave()
    },
  },
  methods: {
    setCubeInfo(cube) {
      if (!cube) {
        this.rectInfo = ''
        return
      }
      switch (this.type) {
        case 0:
          this.rectInfo = '长：[' + cube.length + ']，角度：[' + cube.angleConver + ']'
          break
        case 1:
          this.rectInfo = '宽：[' + cube.width + ']，角度：[' + cube.angleConver + ']'
          break
        case 2:
          this.rectInfo = '高：[' + cube.height + ']，角度：[' + cube.angleConver + ']'
          break
      }
    },
    setCamera() {
      switch (this.type) {
        case 0:
          this.camera.position.set(0, 0, 40)
          break
        case 1:
          this.camera.position.set(40, 0, 0)
          break
        case 2:
          this.camera.position.set(0, 40, 0)
          break
      }
      this.camera.up.set(0, 0, 1)
      this.camera.lookAt(new THREE.Vector3(0, 0, 0))
    },
    init() {
      this.container = document.getElementById('container' + this.id)
      let canvas3d = document.getElementById('canvas3d' + this.id)
      this.raycaster = new THREE.Raycaster()
      this.mouse = new THREE.Vector2()
      this.scene = new THREE.Scene()
      // this.camera = new THREE.PerspectiveCamera(10, this.container.offsetWidth / this.container.offsetHeight, 0.1, 10000);
      let frustumSize = 200
      let aspect = window.innerWidth / window.innerHeight
      this.camera = new THREE.OrthographicCamera(
        (frustumSize * aspect) / -100,
        (frustumSize * aspect) / 100,
        frustumSize / 100,
        frustumSize / -100,
        1,
        100
      )
      this.setCamera()
      this.scene.add(this.camera)

      let ambientLight = new THREE.AmbientLight(0xffffff)
      this.scene.add(ambientLight)

      this.scene = new THREE.Scene()
      this.scene.background = new THREE.Color(0x111111)

      // 添加坐标轴
      // let axesHelper = new THREE.AxesHelper(1);
      // this.scene.add(axesHelper);
      if (this.renderer != null) {
        this.renderer.forceContextLoss()
        this.renderer = null
      }

      this.renderer = new THREE.WebGLRenderer({
        antialias: true,
        canvas: canvas3d,
        powerPreference: 'high-performance',
      })
      this.renderer.setPixelRatio(window.devicePixelRatio)
      this.renderer.setSize(this.container.offsetWidth, this.container.offsetHeight)
      this.container.appendChild(this.renderer.domElement)
      this.clientRect = this.renderer.domElement.getBoundingClientRect()

      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
      this.controls.zoomSpeed = 3
      this.controls.panSpeed = 2
      this.controls.rotateSpeed = 1
      this.controls.maxPolarAngle = Math.PI * 0.5
      this.controls.enableRotate = false

      this.renderer.domElement.addEventListener('mousemove', this.onMouseMove, false)
      this.renderer.domElement.addEventListener('mousedown', this.onMouseDown, false)
      this.renderer.domElement.addEventListener('mouseup', this.onMouseUp, false)
      this.renderer.domElement.addEventListener('wheel', this.onMouseWheel, false)
      this.animate()
    },
    resize() {
      if (this.camera) {
        this.camera.aspect = this.container.offsetWidth / this.container.offsetHeight
        this.renderer.setSize(this.container.offsetWidth, this.container.offsetHeight)
        this.camera.updateProjectionMatrix()
        this.renderer.render(this.scene, this.camera)
      }
    },
    /**
     * 传矩形数据等待渲染
     **/
    rectPoints(cube) {
      this.cube = cube
      this.vertices.splice(0, this.vertices.length)
      for (let p = 0; p < 8; p++) {
        this.vertices.push(
          new THREE.Vector3(
            this.cube.eightPoints[p * 3],
            this.cube.eightPoints[p * 3 + 1],
            this.cube.eightPoints[p * 3 + 2]
          )
        )
      }
      if (this.cube.angle == 0) {
        // 暂时处理，不同方向的立方体起点顺序不一致
        let item = this.vertices.splice(0, 1) //删除 0，把0给item
        this.vertices.splice(3, 0, item[0])
        item = this.vertices.splice(4, 1) //删除 4，把0给item
        this.vertices.splice(7, 0, item[0])
      }
      let viewPoints = this.sortPoints(this.getViewRectPoints(this.type))
      viewPoints.forEach((point, index) => {
        this.setViewRectPoints(this.type, index, point)
      })
      this.setCubeInfo(cube)
      this.oldRectPoints = this.getViewRectPoints(this.type)
    },
    getViewRectPoints(type) {
      if (this.vertices.length > 0) {
        return [
          [this.vertices[4], this.vertices[5], this.vertices[6], this.vertices[7], this.vertices[4]],
          [this.vertices[0], this.vertices[3], this.vertices[7], this.vertices[4], this.vertices[0]],
          [this.vertices[1], this.vertices[5], this.vertices[4], this.vertices[0], this.vertices[1]],
        ][type]
      }
      return []
    },
    setViewRectPoints(type, index, point) {
      if (this.vertices.length > 0) {
        switch (type) {
          case 0:
            switch (index) {
              case 0:
                this.vertices[4] = point
                break
              case 1:
                this.vertices[5] = point
                break
              case 2:
                this.vertices[6] = point
                break
              case 3:
                this.vertices[7] = point
                break
            }
            break
          case 1:
            switch (index) {
              case 0:
                this.vertices[0] = point
                break
              case 1:
                this.vertices[3] = point
                break
              case 2:
                this.vertices[7] = point
                break
              case 3:
                this.vertices[4] = point
                break
            }
            break
          case 2:
            switch (index) {
              case 0:
                this.vertices[1] = point
                break
              case 1:
                this.vertices[5] = point
                break
              case 2:
                this.vertices[4] = point
                break
              case 3:
                this.vertices[0] = point
                break
            }
            break
        }
      }
    },
    sortPoints(points) {
      points.splice(0, 1) //删除 0，把0给item
      points = points.map((point, index) => {
        point.index = index
        return point
      })
      let ps = points
      if (this.type == 0) {
        // 0 调整x,y
        ps = ps.sort((obj1, obj2) => {
          return obj1.x - obj2.x
        })
        ps = ps.sort((obj1, obj2) => {
          return obj1.y - obj2.y
        })
      } else if (this.type == 1) {
        // 1 调整y,z
        ps = ps.sort((obj1, obj2) => {
          return obj1.y - obj2.y
        })
        ps = ps.sort((obj1, obj2) => {
          return obj1.z - obj2.z
        })
      } else if (this.type == 2) {
        // 2 调整x,z
        ps = ps.sort((obj1, obj2) => {
          return obj1.x - obj2.x
        })
        ps = ps.sort((obj1, obj2) => {
          return obj1.z - obj2.z
        })
      }
      let temp = ps[0]
      ps[0] = ps[1]
      ps[1] = temp
      ps.push(ps[0])
      return ps
    },
    /**
     * 渲染矩形
     * */
    planeRender(points) {
      if (this.scene && this.vertices.length > 0 && this.selectedObjectRendered) {
        this.selectedObjectRendered = false
        let geom = new THREE.Geometry()
        geom.vertices = points
        let material = new THREE.PointsMaterial({ color: 0xffffff, size: 10 })
        material.sizeAttenuation = false
        this.planeMesh = new THREE.Points(geom, material)
        this.planeLine = new THREE.Line(geom, this.cube.edgesMaterial)
        this.keyPoints = this.cube.keyPointInfo
          ? new THREE.Points(this.cube.keyPointInfo.geom, this.cube.keyPointInfo.mate)
          : null

        this.removeOldPlaneRender()

        let fillStyle = 'rgb(255,255,255)'
        geom = new THREE.BoxGeometry()
        geom.vertices = this.cube.vertices
        geom.faces = this.cube.faces
        geom.computeFaceNormals()
        let cubeMat1 = new THREE.MeshBasicMaterial({ color: fillStyle, transparent: true, opacity: 0 })
        this.cubeMesh = new THREE.Mesh(geom, cubeMat1) // 立方体几何体box作为EdgesGeometry参数创建一个新的几何体
        let edges = new THREE.EdgesGeometry(geom)
        // // 立方体线框，不显示中间的斜线
        // let edgesMaterial = new THREE.LineBasicMaterial({
        //   color: fillStyle,
        //   opacity: 1,
        //   linewidth: 6
        // })
        this.line = new THREE.LineSegments(edges, this.cube.edgesMaterial)
        // 网格模型和网格模型对应的轮廓线框插入到场景中
        this.scene.add(this.cubeMesh, this.line)

        this.old_planeMesh = this.planeMesh
        this.old_planeLine = this.planeLine
        this.old_keyPoints = this.keyPoints
        this.scene.add(this.old_planeMesh, this.old_planeLine, this.old_keyPoints)
      }
    },
    resetCameraPosition() {
      if (this.vertices.length > 0) {
        // console.log(this.cube.length, this.cube.width, this.cube.height);
        // const distance = 5 * [Math.max(this.cube.length, this.cube.width), Math.max(this.cube.width, this.cube.height), Math.max(this.cube.length, this.cube.height)][this.type]
        // let p = this.calcCameraPosition(distance);
        // let x = p.lookAt.x, y = p.lookAt.y, z = p.lookAt.z;
        // let x1 = p.position.x, y1 = p.position.y, z1 = Math.abs(p.position.z);
        // let x1 = x, y1 = y, z1 = z;
        // if (this.type == 0) { // 垂直看的时候调整摄像机y值比lookAt的y值大，保持和主窗口相同视角
        //   y1 += 0.01;
        // }
        // this.controls.target.copy({x, y, z});
        // this.camera.lookAt(x, y, z);
        // this.camera.position.set(x1, y1, z1);

        // let xxx = this.cube.eightPoints;

        // let centerX = (parseFloat(xxx[0]) + parseFloat(xxx[3]) + parseFloat(xxx[6]) + parseFloat(xxx[9])) / 4.0;
        // let centerY = (parseFloat(xxx[1]) + parseFloat(xxx[4]) + parseFloat(xxx[7]) + parseFloat(xxx[10])) / 4.0;
        // let centerZ = (parseFloat(xxx[2]) + parseFloat(xxx[5]) + parseFloat(xxx[8]) + parseFloat(xxx[11])) / 4.0;

        let x = this.cube.posPoints.pos1.x,
          y = this.cube.posPoints.pos1.y,
          z = this.cube.posPoints.pos1.z
        this.controls.target.copy({ x, y, z })
        this.camera.lookAt(x, y, z)
        if (this.type === 0) {
          // this.camera.lookAt(centerX, centerY, centerZ);
          // console.log("lookat", x, y, z);
          // console.log("position", this.cube.posPoints.pos4.x, this.cube.posPoints.pos4.y, this.cube.posPoints.pos4.z);
          this.camera.position.set(this.cube.posPoints.pos4.x, this.cube.posPoints.pos4.y, this.cube.posPoints.pos4.z)
          this.controls.autoRotate = true
          this.controls.maxAzimuthAngle = this.cube.orientTheta
          this.controls.minAzimuthAngle = this.cube.orientTheta
        } else if (this.type === 1)
          this.camera.position.set(this.cube.posPoints.pos3.x, this.cube.posPoints.pos3.y, this.cube.posPoints.pos3.z)
        else if (this.type === 2)
          this.camera.position.set(this.cube.posPoints.pos2.x, this.cube.posPoints.pos2.y, this.cube.posPoints.pos2.z)
        // this.camera.updateMatrix();
        // this.camera.updateWorldMatrix(true, true);
        this.camera.updateProjectionMatrix()
        this.controls.update()
      }
    },
    removeOldPlaneRender() {
      if (this.old_planeMesh) {
        try {
          if (this.scene) {
            if (this.cubeMesh) this.scene.remove(this.cubeMesh)
            if (this.line) this.scene.remove(this.line)
            this.scene.remove(this.old_planeMesh)
            this.old_planeMesh.geometry.dispose()
            this.old_planeMesh.material.dispose()
            this.scene.remove(this.old_planeLine)
            this.old_planeLine.geometry.dispose()
            this.old_planeLine.material.dispose()
            if (this.old_keyPoints) {
              this.scene.remove(this.old_keyPoints)
              this.old_keyPoints.geometry.dispose()
              this.old_keyPoints.material.dispose()
            }
          }
        } catch (e) {
          console.log(e)
        }
      }
    },
    /**
     * 渲染点云背景
     */
    pointsRender() {
      if (this.pointsCloudData) return // 暂时不加载，干扰内容显示
      try {
        console.log(this.pointsCloudData)
        this.clonePointsCloudData = this.loadJsonPCD(this.pointsCloudData.geometry.attributes.position.array)
      } catch (e) {
        this.clonePointsCloudData = null
        console.error(e)
      }
      if (this.clonePointsCloudData) {
        if (this.points && this.scene) {
          try {
            this.scene.remove(this.points)
            this.points.geometry.dispose()
            this.points.material.dispose()
          } catch (e) {
            console.log(e)
          }
        }
        this.points = this.clonePointsCloudData
        this.scene.add(this.points)
      }
    },
    loadJsonPCD(positionArray) {
      let positions = []
      let color = []
      for (var i = 0; i < positionArray.length / 3; i++) {
        let x = positionArray[i * 3]
        let y = positionArray[i * 3 + 1]
        let z = positionArray[i * 3 + 2]
        positions.push(x, y, z)
        let tmp = colorRender(z, this.renderType)
        color.push(tmp[0], tmp[1], tmp[2])
      }
      let canvas_temp0 = document.createElement('canvas')
      canvas_temp0.width = 100
      canvas_temp0.height = 100
      let context0 = canvas_temp0.getContext('2d')
      context0.fillStyle = '#ffffff'
      context0.arc(50, 50, 45, 0, 2 * Math.PI)
      context0.fill()
      let texture0 = new THREE.Texture(canvas_temp0)
      texture0.needsUpdate = true
      let material = new THREE.PointsMaterial({
        size: 2,
        vertexColors: THREE.VertexColors,
        depthTest: false,
        map: texture0,
      })
      material.color.setHex(0xffffff)
      material.sizeAttenuation = false
      material.vertexColors = THREE.VertexColors
      material.fog = false
      let geometry = new THREE.BufferGeometry()
      geometry.attributes.color = new THREE.Float32BufferAttribute(color, 3)
      geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))
      geometry.computeBoundingSphere()
      return new THREE.Points(geometry, material)
    },
    /**
     * 根据两点坐标求延长点坐标，借中心点计算摄影机坐标
     * cameraDistance 摄影机距离平面的距离
     **/
    calcCameraPosition(cameraDistance) {
      // https://blog.csdn.net/can3981132/article/details/62040993
      // 返回六个面的中心点，根据type计算需要的点
      let centerPoints = this.calcCubePlaneCenterPoints()
      let p1 = centerPoints[0]
      let p2 = centerPoints[1]
      let r = Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y))
      let x = r == 0 ? p1.x : (cameraDistance * (p2.x - p1.x)) / r + p1.x
      let y = r == 0 ? p1.y : (cameraDistance * (p2.y - p1.y)) / r + p1.y
      r = Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.z - p2.z) * (p1.z - p2.z))
      let z = r == 0 ? p1.z : (cameraDistance * (p2.z - p1.z)) / r + p1.z
      return { position: { x: x, y: y, z: z }, lookAt: p1 }
    },
    /**
     * 计算矩形每个面中心点的三维坐标值
     **/
    calcCubePlaneCenterPoints() {
      // 矩形绘制顺序底面：0-1-2-3，对应顶面4-5-6-7
      let points = [
        [
          [this.vertices[0], this.vertices[1], this.vertices[2], this.vertices[3]], //底面
          [this.vertices[4], this.vertices[5], this.vertices[6], this.vertices[7]], //顶面
        ],
        [
          [this.vertices[1], this.vertices[5], this.vertices[6], this.vertices[2]], //右侧
          [this.vertices[0], this.vertices[4], this.vertices[7], this.vertices[3]], //左侧
        ],
        [
          [this.vertices[2], this.vertices[3], this.vertices[7], this.vertices[6]], //后面
          [this.vertices[1], this.vertices[0], this.vertices[4], this.vertices[5]], //前面
        ],
      ][this.type]
      return points.map((planePoints) => {
        let maxx = Math.max(
          ...planePoints.map((point) => {
            return point.x
          })
        )
        let minx = Math.min(
          ...planePoints.map((point) => {
            return point.x
          })
        )
        let maxy = Math.max(
          ...planePoints.map((point) => {
            return point.y
          })
        )
        let miny = Math.min(
          ...planePoints.map((point) => {
            return point.y
          })
        )
        let maxz = Math.max(
          ...planePoints.map((point) => {
            return point.z
          })
        )
        let minz = Math.min(
          ...planePoints.map((point) => {
            return point.z
          })
        )

        let x = (maxx - minx) / 2 + minx,
          y = (maxy - miny) / 2 + miny,
          z = (maxz - minz) / 2 + minz
        return { x: x, y: y, z: z }
      })
    },
    // 计算鼠标位置
    calcMousePosition(x, y, z) {
      let points = this.getViewRectPoints(this.type)
      points.splice(4, 1)
      let minx = 10000,
        miny = 10000,
        minxIndex,
        minyIndex,
        clsxVal,
        clsyVal
      points.forEach((point, index) => {
        if (this.type == 0) {
          // 0 调整x,y
          clsxVal = Math.abs(point.x - x)
          clsyVal = Math.abs(point.y - y)
        } else if (this.type == 1) {
          // 1 调整y,z
          clsxVal = Math.abs(point.y - y)
          clsyVal = Math.abs(point.z - z)
        } else if (this.type == 2) {
          // 2 调整x,z
          clsxVal = Math.abs(point.x - x)
          clsyVal = Math.abs(point.z - z)
        }
        if (clsxVal < minx) {
          minxIndex = index
          minx = clsxVal
        }
        if (clsyVal < miny) {
          minyIndex = index
          miny = clsyVal
        }
      })
      if (minx < miny) {
        // x方向调整
        if (minxIndex == 0) {
          this.moveIndex1 = 0
          this.moveIndex2 = 3
        } else {
          this.moveIndex1 = 1
          this.moveIndex2 = 2
        }
        this.directionx = 2
        this.directiony = 0
      } else {
        // y方向调整
        if (minyIndex == 0) {
          this.moveIndex1 = 0
          this.moveIndex2 = 1
        } else {
          this.moveIndex1 = 2
          this.moveIndex2 = 3
        }
        this.directionx = 0
        this.directiony = 1
      }
      this.renderer.domElement.style.cursor = 'pointer'
    },
    // 移动矩形点变更矩形尺寸
    moveRectPoint() {
      if (this.mouseX == null) {
        this.mouseX = this.mouse.x
        this.mouseY = this.mouse.y
      }
      let x = this.mouse.x - this.mouseX
      let y = this.mouse.y - this.mouseY
      x *= (this.type == 1 ? 2 : 4) * this.directionx
      y *= (this.type == 1 ? 2 : 4) * this.directiony
      x = this.type == 2 ? 0 : x
      y = this.type != 2 ? 0 : y // 每个视图仅调整一个方向
      let points = this.getViewRectPoints(this.type)
      let index1 = this.moveIndex1,
        index2 = this.moveIndex2,
        point1,
        point2
      if (this.type == 0) {
        // 0 调整x,y
        point1 = new THREE.Vector3(points[index1].x - x, points[index1].y - y, points[index1].z)
        point2 = new THREE.Vector3(points[index2].x - x, points[index2].y - y, points[index2].z)
      } else if (this.type == 1) {
        // 1 调整y,z
        point1 = new THREE.Vector3(
          points[index1].x,
          points[index1].y + x * (points[index1].y > 0 ? -1 : 1),
          points[index1].z + y
        )
        point2 = new THREE.Vector3(
          points[index2].x,
          points[index2].y + x * (points[index1].y > 0 ? -1 : 1),
          points[index2].z + y
        )
      } else if (this.type == 2) {
        // 2 调整x,z
        point1 = new THREE.Vector3(
          points[index1].x + x * (points[index1].x > 0 ? -1 : 1),
          points[index1].y,
          points[index1].z + y
        )
        point2 = new THREE.Vector3(
          points[index2].x + x * (points[index1].x > 0 ? -1 : 1),
          points[index2].y,
          points[index2].z + y
        )
      }
      this.setViewRectPoints(this.type, index1, point1)
      this.setViewRectPoints(this.type, index2, point2)
      this.selectedObjectRendered = true
      this.planeRender(this.getViewRectPoints(this.type))
      this.getRectInfo()
      this.mouseX = this.mouse.x
      this.mouseY = this.mouse.y
    },
    getRectInfo() {
      let bb = new THREE.Box3()
      bb.setFromObject(this.planeLine)
      switch (this.type) {
        case 0:
          let length = bb.getSize().x.toFixed(2)
          this.updateRectInfo = '修改后长：[' + length + ']'
          break
        case 1:
          let width = bb.getSize().y.toFixed(2)
          this.updateRectInfo = '修改后宽：[' + width + ']'
          break
        case 2:
          let height = bb.getSize().z.toFixed(2)
          this.updateRectInfo = '修改后高：[' + height + ']'
          break
      }
    },
    cancelSave() {
      this.updateRectInfo = ''
      this.oldRectPoints.forEach((point, index) => {
        this.setViewRectPoints(this.type, index, point)
      })
      this.selectedObjectRendered = true
      this.planeRender(this.getViewRectPoints(this.type))
    },
    // 鼠标按下事件处理
    onMouseDown(event) {
      event.preventDefault()
      this.mouse.x = ((event.clientX - this.clientRect.left) / this.clientRect.width) * 2 - 1
      this.mouse.y = -((event.clientY - this.clientRect.top) / this.clientRect.height) * 2 + 1

      if (event.buttons == 1) {
        this.raycaster.setFromCamera(this.mouse, this.camera)
        let intersects = this.raycaster.intersectObjects(this.scene.children)
        if (intersects.length > 0) {
          if (intersects[0].object != this.INTERSECTED) {
            if (intersects[0].object.type == 'Line') {
              this.mouseDown = true
              this.renderEnabled = true
              this.calcMousePosition(intersects[0].point.x, intersects[0].point.y, intersects[0].point.z)
              // restore previous intersection object (if it exists) to its original color
              // if (this.INTERSECTED )
              //   this.INTERSECTED.material.color.setHex( this.INTERSECTED.currentHex);
              // store reference to closest object as current intersection object
              // this.INTERSECTED = intersects[0].object;
              // store color of closest object (for later restoration)
              // this.INTERSECTED.currentHex = this.INTERSECTED.material.color.getHex();
              // set a new color for closest object
              // this.INTERSECTED.material.color.setHex( 0xffff00 );

              let worldVector = new THREE.Vector3(
                intersects[0].object.geometry.boundingSphere.center.x,
                intersects[0].object.geometry.boundingSphere.center.y,
                intersects[0].object.geometry.boundingSphere.center.z
              )
              //世界坐标转标准设备坐标
              let stdVector = worldVector.project(this.camera)
              let halfWidth = window.innerWidth / 2
              let halfHeight = window.innerHeight / 2
              //标准设备坐标转屏幕坐标x,y
              let x = Math.round(stdVector.x * halfWidth + halfWidth)
              let y = Math.round(-stdVector.y * halfHeight + halfHeight)
              // console.log(x, y, stdVector, worldVector);
            }
          }
        } else {
          // if (this.INTERSECTED){
          //   this.INTERSECTED.material.color.setHex(this.INTERSECTED.currentHex);
          //   this.INTERSECTED = null;
          // }
        }
      }
    },
    onMouseUp(event) {
      event.preventDefault()
      this.mouseDown = false
      this.mouseX = null
      this.mouseY = null
      this.moveIndex1 = null
      this.moveIndex2 = null
      this.directionx = 1
      this.directiony = 1
    },
    // 鼠标移动事件处理
    onMouseMove(event) {
      event.preventDefault()
      this.mouse.x = ((event.clientX - this.clientRect.left) / this.clientRect.width) * 2 - 1
      this.mouse.y = -((event.clientY - this.clientRect.top) / this.clientRect.height) * 2 + 1

      if (this.mouseDown && event.buttons == 1) {
        this.moveRectPoint()
      }
    },
    onMouseWheel(event) {
      this.renderEnabled = true
    },
    animate() {
      if (this.renderer) {
        this.animationFrameId = requestAnimationFrame(this.animate.bind(this))
        if (this.visable) {
          this.controls.update()
          this.renderer.render(this.scene, this.camera)
        }
      }
    },
  },
  beforeDestroy() {
    cancelAnimationFrame(this.animationFrameId)
    this.camera = null
    if (this.renderer) {
      this.renderer.domElement.removeEventListener('mousemove', this.onMouseMove, false)
      this.renderer.domElement.removeEventListener('mousedown', this.onMouseDown, false)
      this.renderer.domElement.removeEventListener('mouseup', this.onMouseUp, false)
      this.renderer.domElement.removeEventListener('wheel', this.onMouseWheel, false)
      this.renderer.forceContextLoss()
      this.renderer = null
    }
  },
}
</script>
<style lang="scss" scoped>
/* Scale canvas with resize attribute to full size */
canvas[resize] {
  width: 100%;
  height: 100%;
}
.plane-view-container {
  width: 100%;
  background: #111;
  border-bottom: 1px solid #fff;
  overflow: hidden;
  position: relative;
}
.title {
  border: 1px solid #888;
  background: #fff;
  padding: 2px 4px;
  position: absolute;
  top: 0;
  border-radius: 0 0 4px;
  font-size: 12px;
}
.rect-info {
  position: absolute;
  top: 0;
  left: 20px;
  width: 100%;
  text-align: center;
  color: #fff;
  margin: 5px 0;
  font-size: 12px;
}
.update-rect-info {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  color: #fff;
  margin: 2px 0;
  font-size: 12px;
  line-height: 20px;
  padding: 0 3px;
  .operator {
    float: right;
  }
}
</style>
